//
// Created on 2024/3/18.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef OHOS_EDITBOXHANDLER_H
#define OHOS_EDITBOXHANDLER_H
#include "napi/editbox/TextComponentsInfo.h"
#include "napi/editbox/TextInfoMap.h"
#include "napi/helper/NapiHelper.h"
class EditBoxHandler{
    public:
        /**--------------------text input callback回调-----------------------**/
        virtual void onTextInputBeginEvent(int32_t id, bool hasFocus, bool isDone) = 0;
        virtual void onTextInputEditingEvent(int32_t id,const char* newString) = 0;
        virtual void onTextInputEnterEvent(int32_t id, bool hasFocus, bool isDone) = 0;

        /**--------------------text area callback回调-----------------------**/
        virtual void onTextAreaBeginEvent(int32_t id, bool hasFocus, bool isDone) = 0;
        virtual void onTextAreaEditingEvent(int32_t id, const char *newString) = 0;
        virtual void onTextAreaEnterEvent(int32_t id, bool hasFocus, bool isDone) = 0;

        /**--------------------text input 相关API回调-----------------------**/
        void createTextInput(int32_t id,int32_t x,int32_t y,int32_t w,int32_t h) {
            JSFunction::getFunction("TextInput.createTextInput").invoke<void>(id, x, y, w, h, 0,0);
            TextInputInfo *textInputInfo = new TextInputInfo();
            TextInfoMap::getInstance()->addTextInputInfo(id, textInputInfo);
        }

        void setTextInputRect(int32_t id, int32_t x,int32_t y,int32_t w,int32_t h) {
            JSFunction::getFunction("TextInput.setTextInputViewRect")
                .invoke<void>(id,  x, y, w, h, 0,0);
        }
    
        const char *GetTextInputText(int32_t id){
            return TextInfoMap::getInstance()->getTextInputInfo(id)->text.c_str();
        }
        bool GetTextInputEditable(int id){
            return TextInfoMap::getInstance()->getTextInputInfo(id)->editable;
        }
        const char *GetTextInputAlign(int id) {
            return TextInfoMap::getInstance()->getTextInputInfo(id)->align.c_str(); 
        }   
        const char *GetTextInputInputType(int id){
            return TextInfoMap::getInstance()->getTextInputInfo(id)->inputType.c_str();
        }
        const char *GetTextInputPlaceHolder(int id){
            return TextInfoMap::getInstance()->getTextInputInfo(id)->placeHolder.c_str();
        }

        void SetTextInputText(int id, const char *text){
            TextInfoMap::getInstance()->getTextInputInfo(id)->text = text;
            JSFunction::getFunction("TextInput.setCurrentText").invoke<void>(id, text);
        }
        void SetTextInputColor(int id, float r, float g, float b, float a){
            TextInfoMap::getInstance()->getTextInputInfo(id)->fontColor = FontColor(r, g, b, a);
            JSFunction::getFunction("TextInput.setTextInputFontColor").invoke<void>(id, r, g, b, a);
        }
        void SetTextInputReturnKey(int id, const char *keyType){
            TextInfoMap::getInstance()->getTextInputInfo(id)->returnType = keyType;
            JSFunction::getFunction("TextInput.setNativeReturnKey").invoke<void>(id, keyType);
        }
        void SetTextInputFontSize(int id, float fontSize){
            TextInfoMap::getInstance()->getTextInputInfo(id)->fontSize = fontSize;
            JSFunction::getFunction("TextInput.setTextInputFontSize").invoke<void>(id, fontSize);
        }
        void SetTextInputFont(int id, const char *fontName, float fontSize, bool isBold){
            TextInfoMap::getInstance()->getTextInputInfo(id)->fontPath = fontName;
            TextInfoMap::getInstance()->getTextInputInfo(id)->fontSize = fontSize;
            TextInfoMap::getInstance()->getTextInputInfo(id)->isBold = isBold;
            JSFunction::getFunction("TextInput.setTextInputFontPath").invoke<void>(id, fontName);
            JSFunction::getFunction("TextInput.setTextInputFontSize").invoke<void>(id, fontSize);
            JSFunction::getFunction("TextInput.setTextInputBold").invoke<void>(id, isBold);
        }
        void SetTextInputInputType(int id, const char *inputType){
            TextInfoMap::getInstance()->getTextInputInfo(id)->inputType = inputType;
            JSFunction::getFunction("TextInput.setNativeInputMode").invoke<void>(id, inputType);
        }
        void SetTextInputInputFlag(int id, bool isSecure){
            TextInfoMap::getInstance()->getTextInputInfo(id)->inputType = isSecure ? "password" : "normal";
            JSFunction::getFunction("TextInput.setNativeInputFlag").invoke<void>(id, isSecure);
        }
        void SetTextInputAlign(int id, const char *align){
            TextInfoMap::getInstance()->getTextInputInfo(id)->align = align;
            JSFunction::getFunction("TextInput.setTextInputAlign").invoke<void>(id, align);
        }
        void SetTextInputEditable(int id, bool editable){
            TextInfoMap::getInstance()->getTextInputInfo(id)->editable = editable;
            JSFunction::getFunction("TextInput.setTextInputEditable").invoke<void>(id, editable);
        }
        void SetTextInputPlaceHolder(int id, const char *placeholder){
            TextInfoMap::getInstance()->getTextInputInfo(id)->placeHolder = placeholder;
            JSFunction::getFunction("TextInput.setTextInputPlaceHolder").invoke<void>(id, placeholder);
        }

        void removeTextInput(int32_t id) {
            JSFunction::getFunction("TextInput.removeTextInput").invoke<void>(id);
            TextInfoMap::getInstance()->deleteTextInputByTag(id);
        }

        /**--------------------text area 相关API回调-----------------------**/
        void createTextArea(int32_t id, int32_t x,int32_t y,int32_t w,int32_t h) {
            JSFunction::getFunction("TextArea.createTextArea")
                .invoke<void>(id, x, y, w, h, 0, 0);
            TextAreaInfo *textAreaInfo = new TextAreaInfo();
            TextInfoMap::getInstance()->addTextAreaInfo(id, textAreaInfo);
        }

        void setTextAreaRect(int32_t id, int32_t x,int32_t y,int32_t w,int32_t h) {
            JSFunction::getFunction("TextArea.setTextAreaViewRect")
                .invoke<void>(id, x, y, w, h, 0, 0);
        }
        const char *GetTextAreaText(int id) { 
            return TextInfoMap::getInstance()->getTextAreaInfo(id)->text.c_str();
        }
        const char *GetTextAreaAlign(int id) { return TextInfoMap::getInstance()->getTextAreaInfo(id)->align.c_str(); }
        const char *GetTextAreaInputType(int id){
            return TextInfoMap::getInstance()->getTextAreaInfo(id)->inputType.c_str();
        }
        const char *GetTextAreaPlaceHolder(int id){
            return TextInfoMap::getInstance()->getTextAreaInfo(id)->placeHolder.c_str();
        }
        bool GetTextAreaEditable(int id){
            return TextInfoMap::getInstance()->getTextAreaInfo(id)->editable;
        }

        void SetTextAreaText(int id, const char *text){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->text = text;
            JSFunction::getFunction("TextArea.setCurrentText").invoke<void>(id, text);
        }
        void SetTextAreaColor(int id, float r, float g, float b, float a){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->fontColor = FontColor(r, g, b, a);
            JSFunction::getFunction("TextArea.setTextAreaFontColor").invoke<void>(id, r, g, b, a);
        }
        void SetTextAreaReturnKey(int id, const char *keyType){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->returnType = keyType;
            JSFunction::getFunction("TextArea.setNativeReturnKey").invoke<void>(id, keyType);
        }
        void SetTextAreaFontSize(int id, float fontSize){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->fontSize = fontSize;
            JSFunction::getFunction("TextArea.setTextAreaFontSize").invoke<void>(id, fontSize);
        }
        void SetTextAreaFont(int id, const char *fontName, float fontSize, bool isBold){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->fontPath = fontName;
            TextInfoMap::getInstance()->getTextAreaInfo(id)->fontSize= fontSize;
            TextInfoMap::getInstance()->getTextAreaInfo(id)->isBold = isBold;
            JSFunction::getFunction("TextArea.setTextAreaFontPath").invoke<void>(id, fontName);
            JSFunction::getFunction("TextArea.setTextAreaFontSize").invoke<void>(id, fontSize);
            JSFunction::getFunction("TextArea.setTextAreaBold").invoke<void>(id, isBold);
        }
        void SetTextAreaInputType(int id, const char *inputType){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->inputType = inputType;
            JSFunction::getFunction("TextArea.setNativeInputMode").invoke<void>(id, inputType);
        }
        void SetTextAreaInputFlag(int id, bool isSecure){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->inputType = isSecure ? "password" : "normal";
            JSFunction::getFunction("TextArea.setNativeInputFlag").invoke<void>(id, isSecure);
        }
        void SetTextAreaAlign(int id, const char *align){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->align = align;
            JSFunction::getFunction("TextArea.setTextAreaAlign").invoke<void>(id, align);
        }
        void SetTextAreaEditable(int id, bool editable){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->editable = editable;
            JSFunction::getFunction("TextArea.setTextAreaEditable").invoke<void>(id, editable);
        }
        void SetTextAreaPlaceHolder(int id, const char *placeholder){
            TextInfoMap::getInstance()->getTextAreaInfo(id)->text = placeholder;
            JSFunction::getFunction("TextArea.setTextAreaPlaceHolder").invoke<void>(id, placeholder);
        }

        void removeTextArea(int32_t id) {
            JSFunction::getFunction("TextArea.removeTextArea").invoke<void>(id);
            TextInfoMap::getInstance()->deleteTextAreaByTag(id);
        }

        static  EditBoxHandler* getInstance(){
            return instance;
        }
    protected:
        static EditBoxHandler* instance;
};
#endif //OHOS_EDITBOXHANDLER_H
